/*! chinapnr UED widget - v0.00.1 - 2013-06-25*/

(function( $, undefined ) {
    $.ued = $.ued || {};
})( jQuery );
//---------------------------//
//下面开始datepicker ui组件代码//
//---------------------------//
//调用方式为：
//ued="{'datepicker':'true,true,0'}"
//三个参数分别为：是否显示日历的图标，是否可编辑input输入框，使用第几套样式表，默认为true，false，0
(function( $, undefined ) {
//文件开始部分代码为$扩展了$.ui对象，此处为$.ui扩展datepicker对象
    $.extend($.ued, { datepicker: { version: "1.10.3" } });

//PROP_NAME：一个常量，绑定后的tag都会有此class----instActive当前操作日历的实例，只所有日历中正在操作的那个
    var PROP_NAME = "datepicker",
        instActive;

    function Datepicker() {
        this._curInst = null; // The current instance in use
        this._datepickerShowing = false; // True if the popup picker is showing , false if not
        this._mainDivId = "ued-datepicker-div"; // The ID of the main datepicker division
        this._unselectableClass = "ued-datepicker-unselectable"; // The name of the unselectable cell marker class
        this._currentClass = "ued-datepicker-current-day"; // The name of the current day marker class
        this._dayOverClass = "ued-datepicker-days-cell-over"; // The name of the day hover marker class
        this.regional = []; // Available regional settings, indexed by language code
        this.regional[""] = { // Default regional settings
            monthNames: ["一月","二月","三月","四月","五月","六月",
                "七月","八月","九月","十月","十一月","十二月"], // Names of months for drop-down and formatting
            monthNamesShort: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"], // For formatting
            dayNamesMin: ["日","一","二","三","四","五","六"], // Column headings for days starting at Sunday
            dateFormat: "yymmdd" // See format options on parseDate
        };
        this._defaults = { // Global defaults for all the date picker instances
            yearRange: "c-5:c+5", // Range of years to display in drop-down,
            showOtherMonths: true, // True to show dates in other months, false to leave blank
            selectOtherMonths: false// True to allow selection of dates in other months, false for unselectable
        };
        $.extend(this._defaults, this.regional[""]);
        this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ued-datepicker ued-widget ued-widget-content ued-helper-clearfix'></div>"));
    }


    $.extend(Datepicker.prototype, {
        markerClassName: "hasDatepicker",

        //用_newInst创建一个新的对象实例，并把前台html中设置的settings复制到对象的settings属性中
        //用_connectDatepicker继续为实例添加append和trigger对象，并通过全局常量markerClassName判断有没有初始化过该对象，没有则用_attachments为该input添加标记和附件（图标按钮等）
        //这是函数的入口
        _attachDatepicker: function(target, settings) {
            var inst;
            inst = this._newInst($(target));
            inst.settings = $.extend({}, settings || {});//扩展当前jquery对象inst的settings属性
            this._connectDatepicker(target, inst);
        },

        //创建一个新的对象实例，如果该实例不destory~无论是显示在哪里，都是这个实例，只是位置和设置不同
        _newInst: function(target) {
            var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1");
            return {id: id, input: target, // associated target
                selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
                drawMonth: 0, drawYear: 0, // month being drawn
                dpDiv:this.dpDiv};
        },

        //为实例添加append和trigger对象,添加标记和附件
        _connectDatepicker: function(target, inst) {
            //将当前input的dom对象转为jquery对象
            var input = $(target);
            inst.append = $([]);
            if (input.hasClass(this.markerClassName)) {
                return;
            }
            input.focus(this._showDatepicker);
            input.addClass(this.markerClassName)
            //为当前的dom对象添加名为PROP_NAME的data以供以后使用,只能在jq1.43版本之后才能出用data赋对象
            $.data(target, PROP_NAME, inst);
        },

        //获取对象中的PROP_NAME值,PROP_NAME在_connectDatepicker已重新赋值过
        _getInst: function(target) {
            try {
                return $.data(target, PROP_NAME);
            }
            catch (err) {
                throw "不存在用于生成日历的实例";
            }
        },


        //显示日历，这边的input是dom对象
        _showDatepicker: function(input) {
            input = input.target || input;
            var inst, isFixed, offset;

            //////////////////////////////
            //把当前input赋值给_lastInput属性
            //////////////////////////////
            inst = $.datepicker._getInst(input);

            $.datepicker._setDateFromField(inst);


            //找到input的为止，并把_pos[1]即y坐标加上input的高度以显示在input下方
            if (!$.datepicker._pos) { // position below input
                $.datepicker._pos = $.datepicker._findPos(input);
                $.datepicker._pos[1] += input.offsetHeight; // add the height
            }
            //_pos是一个数组第一位是x坐标，第二位是y坐标
            offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
            $.datepicker._pos = null;
            inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});


            ///////////////////////////////////
            //在window.jquery下有个datepicker对象
            ///////////////////////////////////
            $.datepicker._updateDatepicker(inst);


            // fix width for dynamic number of date pickers
            // and adjust position before showing
            offset = $.datepicker._checkOffset(inst, offset, isFixed);
            inst.dpDiv.css({position: "absolute", display: "none",
                left: offset.left + "px", top: offset.top + "px"});
            $.datepicker._datepickerShowing = true;
            inst.dpDiv.css("zIndex",$(input).css("zIndex")+1).show();

            ////////////////////////////
            //在jquery下有个datepicker对象
            ////////////////////////////
            $.datepicker._lastInput = input;
            $.datepicker._curInst = inst;

        },

        //即重新生成一遍datePicker的内容
        _updateDatepicker: function(inst) {
            instActive = inst; // for delegate hover events
            inst.dpDiv.empty().append(this._generateHTML(inst));
            this._attachHandlers(inst);
        },


        //定位函数
        _checkOffset: function(inst, offset, isFixed) {
            var dpWidth = inst.dpDiv.outerWidth(),
                dpHeight = inst.dpDiv.outerHeight(),
                inputWidth = inst.input ? inst.input.outerWidth() : 0,
                inputHeight = inst.input ? inst.input.outerHeight() : 0,
                viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
                viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());

            offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
            offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;

            // now check if datepicker is showing outside window viewport - move to a better place if so.
            offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
                Math.abs(offset.left + dpWidth - viewWidth) : 0);
            offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
                Math.abs(dpHeight + inputHeight) : 0);
            return offset;
        },
        //定位函数
        _findPos: function(obj) {
            var position;
            while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
                obj = obj["nextSibling"];
            }

            position = $(obj).offset();
            return [position.left, position.top];
        },

        //隐藏日历
        _hideDatepicker: function(input) {
            var inst = this._curInst;
            if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
                return;
            }

            if (this._datepickerShowing) {
                //去除多余动画支持
                inst.dpDiv.hide();
                this._datepickerShowing = false;
                this._lastInput = null;
            }
        },

        //判断是否在日历外部和触发开关的外部点击
        _checkExternalClick: function(event) {
            if (!$.datepicker._curInst) {
                return;
            }
            var $target = $(event.target),
                inst = $.datepicker._getInst($target[0]);

            if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
                $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
                !$target.hasClass($.datepicker.markerClassName) &&
                $.datepicker._datepickerShowing) ) || ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
                $.datepicker._hideDatepicker();
            }
        },

        //根据period类型来变更显示的日期
        _adjustDate: function(id, offset, period) {
            var target = $(id),
                inst = this._getInst(target[0]);
            this._adjustInstDate(inst, offset, period);
            this._updateDatepicker(inst);
        },



        //选择日期
        _selectDay: function(id, month, year, td) {
            var inst,
                target = $(id);

            if ($(td).hasClass(this._unselectableClass)) {
                return;
            }

            inst = this._getInst(target[0]);
            inst.selectedDay = inst.currentDay = $("a", td).html();
            inst.selectedMonth = inst.currentMonth = month;
            inst.selectedYear = inst.currentYear = year;
            this._selectDate(id, this._formatDate(inst,
                inst.currentDay, inst.currentMonth, inst.currentYear));
        },

        //设置input的值
        _selectDate: function(id, dateStr) {
            var target = $(id),
                inst = this._getInst(target[0]);

            dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
            if (inst.input) {
                inst.input.val(dateStr);
            }
            this._lastInput = inst.input[0];
            this._hideDatepicker();
            this._lastInput = null;
        },

        //格式化输出到input中的日期
        formatDate: function (format, date, settings) {
            if (!date) {
                return "";
            }

            var formatNumber = function(match, value, len) {
                    var num = "" + value;
                    while (num.length < len) {
                        num = "0" + num;
                    }
                    return num;
                },

                output = "";
            output += date.getFullYear();
            output += "-";
            output += formatNumber("m", date.getMonth() + 1, 2);
            output += "-";
            output += formatNumber("d", date.getDate(), 2);

            return output;
        },

        //获取参数的方法
        _get: function(inst, name) {
            return inst.settings[name] !== undefined ?
                inst.settings[name] : this._defaults[name];
        },

        //初始化数据
        _setDateFromField: function(inst, noDefault) {
            if (inst.input.val() === inst.lastVal) {
                return;
            }

            var dates = /*inst.lastVal = */inst.input ? inst.input.val() : null,
                currentTime = dates.split('-'),
                currentYear = currentTime[0],
                currentMonth = currentTime[1],
                currentDay = currentTime[2],
                date;
                (currentYear && currentMonth && currentDay)? (date = new Date(currentYear, currentMonth-1, currentDay)): (date = new Date());
            inst.selectedDay = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
                new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
            inst.drawMonth = inst.selectedMonth = date.getMonth();
            inst.drawYear = inst.selectedYear = date.getFullYear();
            inst.currentDay = (dates ? date.getDate() : 0);
            inst.currentMonth = (dates ? date.getMonth() : 0);
            inst.currentYear = (dates ? date.getFullYear() : 0);
        },


        //绑定事件
        _attachHandlers: function(inst) {
            var id = "#" + inst.id.replace( /\\\\/g, "\\" );
            inst.dpDiv.find("[data-handler]").map(function () {
                var handler = {
                    preYear: function () {
                        $.datepicker._adjustDate(id, -1, "Y");
                    },
                    nexYear: function () {
                        $.datepicker._adjustDate(id, +1, "Y");
                    },
                    prev: function () {
                        $.datepicker._adjustDate(id, -1, "M");
                    },
                    next: function () {
                        $.datepicker._adjustDate(id, +1, "M");
                    },
                    hide: function () {
                        $.datepicker._hideDatepicker();
                    },
                    selectDay: function () {
                        $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
                        return false;
                    }
                };
                $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
            });
        },

        //生成HTML
        _generateHTML: function(inst) {
            var prev, next,prevYear,nextYear,
                firstDay, dayNamesMin,
                monthNames, monthNamesShort, showOtherMonths,
                selectOtherMonths, html, dow,
                calender, thead, day, daysInMonth, leadDays,
                printDate, dRow, tbody, daySettings, otherMonth, unselectable,
                tempDate = new Date(),
                today = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate()),
                showButtonPanel = this._get(inst, "showButtonPanel"),
                stepMonths = this._get(inst, "stepMonths"),
                currentDate = (!inst.currentDay ? new Date(9999, 9, 9) :
                    new Date(inst.currentYear, inst.currentMonth, inst.currentDay)),
                drawMonth = inst.drawMonth,
                drawYear = inst.drawYear;



            if (drawMonth < 0) {
                drawMonth += 12;
                drawYear--;
            }

            prev = "<a class='ued-datepicker-prev' data-handler='prev' data-event='click'" +
                " title='下个月'><span class='ued-icon ued-icon-circle-triangle-mw'></span></a>";
            prevYear = "<a class='ued-datepicker-preYear' data-handler='preYear' data-event='click'" +
                " title='上一年'><span class='ued-icon ued-icon-circle-triangle-w'></span></a>";

            next = "<a class='ued-datepicker-next' data-handler='next' data-event='click'" +
                " title='上个月'><span class='ued-icon ued-icon-circle-triangle-me'></span></a>"
            nextYear = "<a class='ued-datepicker-nexYear' data-handler='nexYear' data-event='click'" +
                " title='上一年'><span class='ued-icon ued-icon-circle-triangle-e'></span></a>"
            firstDay = parseInt(0,10);
            dayNamesMin = this._get(inst, "dayNamesMin");
            monthNames = this._get(inst, "monthNames");
            monthNamesShort = this._get(inst, "monthNamesShort");
            showOtherMonths = this._get(inst, "showOtherMonths");
            selectOtherMonths = this._get(inst, "selectOtherMonths");
            html = "";
            calender = "";
            calender += "<div class='ued-datepicker-header ued-widget-header ued-helper-clearfix'>" + prevYear + prev + next + nextYear+
                this._generateMonthYearHeader(inst, drawMonth, drawYear, monthNames, monthNamesShort) + // draw month headers
                "</div><table class='ued-datepicker-calendar' cellpadding='0' cellspacing='0' border='0' rules='all' ><thead>" +
                "<tr>";
            //去除显示周功能
            thead = "";
            for (dow = 0; dow < 7; dow++) { // days of the week
                day = (dow) % 7;
                thead += "<th>" + dayNamesMin[day] + "</span></th>";
            }
            calender += thead + "</tr></thead><tbody>";
            daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
            if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
                inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
            }
            leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
            printDate = new Date(drawYear, drawMonth, 1 - leadDays);
            for (dRow = 0; dRow < 6; dRow++) { // create date picker rows
                calender += "<tr>";
                //去除周显示
                tbody = "";
                for (dow = 0; dow < 7; dow++) {
                    daySettings = [true, ""];
                    otherMonth = (printDate.getMonth() !== drawMonth);
                    unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ;
                    tbody += "<td class='" +
                        ((dow + firstDay + 6) % 7 >= 5 ? " ued-datepicker-week-end" : "") + // highlight weekends
                        (otherMonth ? " ued-datepicker-other-month" : "") + // highlight days from other months
                        (unselectable ? " " + this._unselectableClass + " ued-state-disabled": "") +  // highlight unselectable days
                        (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
                            (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
                            (printDate.getTime() === today.getTime() ? " ued-datepicker-today" : "")) + "'" + // highlight today (if different)
                        ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
                        (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
                        (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
                            (unselectable ? "<span class='ued-state-default'>" + printDate.getDate() + "</span>" : "<a class='ued-state-default" +
                                (printDate.getTime() === today.getTime() ? " ued-state-highlight" : "") +
                                (printDate.getTime() === currentDate.getTime() ? " ued-state-active" : "") + // highlight selected day
                                (otherMonth ? " ued-priority-secondary" : "") + // distinguish dates from other months
                                "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
                    printDate.setDate(printDate.getDate() + 1);
                }
                calender += tbody + "</tr>";
            }
            calender += "</tbody></table>";
            html += calender;
            return html;
        },

        _generateMonthYearHeader: function(inst, drawMonth, drawYear, monthNames, monthNamesShort) {
            var month, years, thisYear, determineYear, year, endYear,
                html = "<div class='ued-datepicker-title'>",
                monthHtml = "";
            monthHtml += "<span class='ui-datepicker-month'>" + (parseInt(drawMonth)+1) + "月</span>";

            if ( !inst.yearshtml ) {
                inst.yearshtml = "";
                // determine range of years to display
                years = this._get(inst, "yearRange").split(":");
                thisYear = new Date().getFullYear();
                determineYear = function(value) {
                    var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
                        (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
                            parseInt(value, 10)));
                    return (isNaN(year) ? thisYear : year);
                };
                year = determineYear(years[0]);
                endYear = Math.max(year, determineYear(years[1] || ""));
                year = year;
                endYear = endYear;
                html += "<span class='ui-datepicker-year'>" + drawYear + "年</span>"
            }

            html += monthHtml;
            html += "</div>";
            return html;
        },

        //调整日期显示，inst是当前input日历的参数对象，offset为时间偏移量，period为偏移类型
        _adjustInstDate: function(inst, offset, period) {
            var year = inst.drawYear + (period === "Y" ? offset : 0),
                month = inst.drawMonth + (period === "M" ? offset : 0),
                day = this._getDaysInMonth(year, month) + (period === "D" ? offset : 0),
                date = new Date(year, month, day);
            inst.selectedDay = date.getDate();
            inst.drawMonth = inst.selectedMonth = date.getMonth();
            inst.drawYear = inst.selectedYear = date.getFullYear();

        },



        //返回每月的天数
        _getDaysInMonth: function(year, month) {
            return 32 - new Date(year, month, 32).getDate();
        },

        //返回每月第一天
        _getFirstDayOfMonth: function(year, month) {
            return new Date(year, month, 1).getDay();
        },

        //格式化日期
        _formatDate: function(inst, day, month, year) {
            if (!day) {
                inst.currentDay = inst.selectedDay;
                inst.currentMonth = inst.selectedMonth;
                inst.currentYear = inst.selectedYear;
            }
            var date = (day ? (typeof day === "object" ? day :
                new Date(year, month, day)) :
                new Date(inst.currentYear, inst.currentMonth, inst.currentDay));

            return this.formatDate(this._get(inst, "dateFormat"), date);
        }
    });


    function bindHover(dpDiv) {
        var selector = "button, .ued-datepicker-prev, .ued-datepicker-next,.ued-datepicker-preYear,.ued-datepicker-nexYear, .ued-datepicker-calendar td a";
        return dpDiv.delegate(selector, "mouseout", function() {
            $(this).removeClass("ued-state-hover");
            if (this.className.indexOf("ued-datepicker-prev") !== -1) {
                $(this).removeClass("ued-datepicker-prev-hover");
            }
            if (this.className.indexOf("ued-datepicker-next") !== -1) {
                $(this).removeClass("ued-datepicker-next-hover");
            }
            if (this.className.indexOf("ued-datepicker-preYear") !== -1) {
                $(this).removeClass("ued-datepicker-preYear-hover");
            }
            if (this.className.indexOf("ued-datepicker-nexYear") !== -1) {
                $(this).removeClass("ued-datepicker-nexYear-hover");
            }
        })
            .delegate(selector, "mouseover", function(){
                $(this).parents(".ued-datepicker-calendar").find("a").removeClass("ued-state-hover");
                $(this).addClass("ued-state-hover");
                if (this.className.indexOf("ued-datepicker-prev") !== -1) {
                    $(this).addClass("ued-datepicker-prev-hover");
                }
                if (this.className.indexOf("ued-datepicker-next") !== -1) {
                    $(this).addClass("ued-datepicker-next-hover");
                }
                if (this.className.indexOf("ued-datepicker-preYear") !== -1) {
                    $(this).addClass("ued-datepicker-preYear-hover");
                }
                if (this.className.indexOf("ued-datepicker-nexYear") !== -1) {
                    $(this).addClass("ued-datepicker-nexYear-hover");
                }
            });
    }

    //dpk初始化
    $.fn.datepicker = function(options){
        if ( !this.length ) {
            return this;
        }

        if (!$.datepicker.initialized) {
            $(document).mousedown($.datepicker._checkExternalClick);
            $.datepicker.initialized = true;
        }

        if ($("#"+$.datepicker._mainDivId).length === 0) {
            $('body').append($.datepicker.dpDiv);
        }

        return this.each(function() {
            $.datepicker._attachDatepicker(this, options);
        });
    };

    $.datepicker = new Datepicker(); // singleton instance
    $.datepicker.initialized = false;
    $.datepicker.uuid = new Date().getTime();

    $(document).ready(function(){
        $("input[ued]").each(function(i){
            var str = $(this).attr('ued').replace(/\'/g,"\""),
                option = $.parseJSON(str).datepicker.split(','),
                inputId,hasIcon,canEdit,styleType;
            if(option.length!=2){
                hasIcon = true;
                canEdit = false;
                //styleType = 0;
            }
            else{
                hasIcon = option[0];
                canEdit = option[1];
                //styleType = option[2];
            }
            inputId = $(this).attr('id')? ($(this).attr('id')) : ('ued-uid-'+new Date().getTime());
            //变更样式
            $(this).addClass('input-style');
            if(hasIcon==='false'){
                $(this).css('background-image','none')
            }
            if(canEdit==='false'){
                $(this).attr('readonly','readonly')
            }

            //初始化
            $(this).attr('id',inputId).datepicker();
        })
    })
})(jQuery);

